﻿using System.Collections.Generic;
using System.Linq;
using Missbot.Common;
using Missbot.Core.Base;
using Dolany.UtilityTool;
using JetBrains.Annotations;
using Missbot.AIModule.Base;
using Missbot.Core.Cache;
using Missbot.Core.CrossingRoute;

namespace Missbot.AIModule.Sys
{
    [UsedImplicitly]
    public class HelpMod : IAIModule, IDataMgr
    {
        public override string Name => "帮助功能";
        public override string ParentTag => "系统功能";

        private List<ExtraHelp> ExtraHelps { get; set; }

        private static AIModuleMgr AIModuleMgr => AutofacSvc.Resolve<AIModuleMgr>();

        public void RefreshData()
        {
            ExtraHelps = ExtraHelpDA.GetAll();
        }

        [ModuleEnter(Command = "帮助", Description = "获取帮助列表")]
        public bool HelpMe(InboxSession session)
        {
            var versionAi = AutofacSvc.Resolve<VersionMod>();
            var version = versionAi.Versions.First();

            var buffer = new OutputBuffer(session);
            buffer.Add($"当前版本为：{version.VersionNum}，请使用 【版本信息】 命令获取当前版本的更新内容！");
            buffer.Add("当前版本的命令标签有：");
            var tags = AIModuleMgr.AllModules.Where(m => m.EnterUnits.Any(enter => enter.Attr.ChannelType.HasFlag(session.Channel.BindingType)))
                                  .Select(c => string.IsNullOrEmpty(c.ParentTag) ? c.Name : c.ParentTag)
                                  .Distinct()
                                  .ToList();

            var tagMsg = string.Join("", tags.Select((tag, idx) =>
            {
                return (idx % 3) switch
                {
                    0 => $"❀**{tag}**❀",
                    1 => $"**{tag}**❀",
                    _ => $"**{tag}**❀\n"
                };
            }));

            buffer.Add(tagMsg);
            buffer.Add("可以使用 **帮助 [标签名]** 来查询标签中的具体命令名 或者使用 **帮助 [命令名]** 来查询具体命令信息。");
            buffer.Send();
            return true;
        }

        [ModuleEnter(Command = "帮助", Description = "获取特定命令或标签的帮助信息")]
        public bool HelpMe_Command(InboxSession session, string name)
        {
            if (HelpCommand(session, name))
            {
                return true;
            }

            if (HelpParentTag(session, name))
            {
                return true;
            }

            if (HelpTag(session, name))
            {
                return true;
            }

            if (GetExtraHelp(session, name))
            {
                return true;
            }

            session.SendBack("很抱歉，未找到相关帮助信息！");
            return false;
        }

        private bool GetExtraHelp(InboxSession session, string name)
        {
            var help = ExtraHelps.FirstOrDefault(p => p.Alias.Contains(name));
            if (help == null)
            {
                return false;
            }

            var msg = $"{help.Name}:{help.HelpMsg}";
            session.SendBack(msg);
            return true;
        }

        private bool HelpCommand(InboxSession session, string name)
        {
            foreach (var module in AIModuleMgr.AllModules)
            {
                var commands = module.EnterUnits.Where(enter => enter.Attr.ChannelType.HasFlag(session.Channel.BindingType))
                                     .Where(c => c.Attr.Command.Split(" ").Contains(name))
                                     .ToList();

                if (commands.IsNullOrEmpty())
                {
                    continue;
                }

                foreach (var command in commands)
                {
                    var buffer = new OutputBuffer(session);
                    buffer.AddPair(new Dictionary<string, string>
                    {
                        ["命令"] = command.Attr.Command,
                        ["格式"] = $"{command.Attr.Command} {command.Attr.SyntaxHint}",
                        ["描述"] = command.Attr.Description,
                        ["权限"] = command.Attr.AuthLvl.ToString(),
                        ["标签"] = string.IsNullOrEmpty(module.ParentTag) ? module.Name : $"{module.ParentTag}-{module.Name}",
                        ["次数限制"] = command.Attr.DailyLimit.ToString()
                    });
                    buffer.Send();
                }

                return true;
            }

            return false;
        }

        private bool HelpParentTag(InboxSession session, string name)
        {
            var modules = AIModuleMgr.AllModules.Where(p => p.ParentTag == name);
            if (modules.IsNullOrEmpty())
            {
                return false;
            }

            var buffer = new OutputBuffer(session);
            buffer.Add($"【{name}】");
            buffer.Add("当前标签下的子标签有：");
            buffer.Add(modules.Select(module => $"**{module.Name}**"));
            buffer.Add("可以使用 **帮助 [标签名]** 来查询标签中的具体命令名 或者使用 **帮助 [命令名]** 来查询具体命令信息。");

            buffer.Send();
            return true;
        }

        private bool HelpTag(InboxSession session, string name)
        {
            var module = AIModuleMgr.AllModules.FirstOrDefault(m => m.Name == name);
            if (module == null)
            {
                return false;
            }

            var enters = module.EnterUnits.Where(enter => enter.Attr.ChannelType.HasFlag(session.Channel.BindingType));
            if (enters.IsNullOrEmpty())
            {
                return false;
            }

            var enterGroup = enters.GroupBy(p => p.Attr.ID);
            var subCommands = enterGroup.Select(enter => string.Join("/", enter.Select(p => p.Attr.Command))).Distinct();

            var buffer = new OutputBuffer(session);
            buffer.Add($"【{name}】");
            if (!string.IsNullOrEmpty(module.ParentTag))
            {
                buffer.AddPair("父级标签", $"**{module.ParentTag}**");
            }

            buffer.Add("当前标签下的命令有：");
            buffer.Add(subCommands.Select(c => $"**{c}**"));
            buffer.Add("可以使用 **帮助 [标签名]** 来查询标签中的具体命令名 或者使用 **帮助 [命令名]** 来查询具体命令信息。");

            buffer.Send();
            return true;
        }

        [ModuleEnter(Command = "查看", Description = "查看某个东西（物品/成就/礼物等等）", SyntaxHint = "[名称]")]
        public bool ViewSomething(InboxSession session, string name)
        {
            var (canView, viewCommand) = CrossingRouteFactory.Instance.CheckViewable(name);
            if (canView)
            {
                session.Text = $"{viewCommand} {name}";
                AIModuleMgr.OnInbox(session);
            }
            else
            {
                session.SendBack("未查找到相关信息！");
            }

            return false;
        }

        [ModuleEnter(Command = "学习", Description = "学习某个技能/菜谱/...", SyntaxHint = "[名称]")]
        public bool LearnSomething(InboxSession session, string name)
        {
            var (canLearn, learnCommand) = CrossingRouteFactory.Instance.CheckLearnable(name);
            if (canLearn)
            {
                session.Text = $"{learnCommand} {name}";
                AIModuleMgr.OnInbox(session);
            }
            else
            {
                session.SendBack("未查找到相关信息！");
            }

            return false;
        }

        [ModuleEnter(Command = "兑换", Description = "兑换菜谱/礼物/...", SyntaxHint = "[名称]")]
        public bool ExchangeSomething(InboxSession session, string name)
        {
            var (canExchange, exchangeCommand) = CrossingRouteFactory.Instance.CheckExchangable(name);
            if (canExchange)
            {
                session.Text = $"{exchangeCommand} {name}";
                AIModuleMgr.OnInbox(session);
            }
            else
            {
                session.SendBack("未查找到相关信息！");
            }

            return false;
        }
    }
}